package com.fuyin.service.user.impl;

import java.util.*;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.fuyin.commons.exception.ApiException;
import com.fuyin.commons.response.BaseResponse;
import com.fuyin.commons.response.ErrorCode;
import com.fuyin.commons.utils.JwtTokenUtil;
import com.fuyin.commons.utils.MyUtils;
import com.fuyin.dao.*;
import com.fuyin.dto.vo.*;
import com.fuyin.entity.*;
import com.fuyin.service.api.PythonApiService;
import com.fuyin.service.user.GpService;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @author yuanxilan (yuanxilan@keep.com)
 * @Description
 * @date 2021年11月05日 4:26 下午
 * @since
 */
@Service
@Slf4j
public class GpServiceImpl implements GpService {

    private static Map<Integer, String> modelAbilityMap = new HashMap<>();

    @Autowired
    private GpDao gpDao;

    @Autowired
    private ZbDao zbDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private PythonApiService pythonApiService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private ReportDao reportDao;

    @Autowired
    private ProductDao productDao;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    static {
        modelAbilityMap.put(0, "较弱");
        modelAbilityMap.put(1, "较强");
    }

    @Override
    public BaseResponse<RiskReport> getRiskReport(String token, String gpName) {
        MyUtils.checkParams("股票名称不能为空", gpName);
        token = StringUtils.substring(token, tokenHead.length());
        User user = userDao.getUserByUserName(jwtTokenUtil.getUserNameFromToken(token));
        RiskReport riskReport = new RiskReport();
        ArrayList<Zcfz> zcfzs = (ArrayList<Zcfz>) gpDao.getZcfzList(gpName);
        zcfzs = (ArrayList<Zcfz>) zcfzs.stream()
                .sorted((o1, o2) -> o1.getReportDate().getTime() > o2.getReportDate().getTime() ? -1 : 1)
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(zcfzs)) {
            try {
                pythonApiService.saveData(gpName);
                // Thread.sleep(5000);
            } catch (Exception e) {
                log.error("com.fuyin.service.user.impl.GpServiceImpl.getRiskReport userName:{},  e:{}, gpName:{}",
                        user.getUserName(), e.getMessage(), gpName);
                return BaseResponse.error(ErrorCode.GP_NOT_SUPPORTED, "暂时不支持该股票的爬取");
            }
            zcfzs = (ArrayList<Zcfz>) gpDao.getZcfzList(gpName);
        }
        // try {
        // log.info("zcfzs: {}", zcfzs.get(0));
        // zcfzs.get(0).setReportDate(parseDayDate(new
        // SimpleDateFormat("yyyy-MM-dd").format(zcfzs.get(0).getReportDate())));
        // } catch (ParseException e) {
        // e.printStackTrace();
        // }
        CompanyInfo companyInfo = gpDao.getCompanyInfoList(gpName);
        ArrayList<Mainzb> mainzbs = (ArrayList<Mainzb>) gpDao.getMainzbList(gpName);
        ArrayList<Profile> profiles = (ArrayList<Profile>) gpDao.getProfileList(gpName);
        log.info("profiles.size(): {}", profiles.size());
        // log.info("profiles: {}", profiles);
        profiles = (ArrayList<Profile>) profiles.stream()
                .sorted((o1, o2) -> o1.getReportDate().getTime() > o2.getReportDate().getTime() ? -1 : 1)
                .collect(Collectors.toList());
        log.info("profiles.size(): {}", profiles.size());
        // log.info("profiles: {}", profiles);
        if (CollectionUtils.isEmpty(profiles)) {
            log.error("抓取不到股票信息，gpName: {}, userName: {}", gpName, jwtTokenUtil.getUserNameFromToken(token));
            return BaseResponse.error(ErrorCode.GP_NOT_FOUND, "抓取不到股票信息");
        }
        ArrayList<Qygqjg> qygqjgs = (ArrayList<Qygqjg>) gpDao.getQygqjgList(profiles.get(0).getSecurityCode());
        ArrayList<Xjll> xjlls = (ArrayList<Xjll>) gpDao.getXjllList(gpName);

        Mainzb lastMainzb = mainzbs.stream()
                .sorted((o1, o2) -> o1.getReportDate().getTime() > o2.getReportDate().getTime() ? -1 : 1)
                .collect(Collectors.toList()).get(0);
        // log.info("lastMainzb: {}", lastMainzb);

        zcfzs = (ArrayList<Zcfz>) getRecentYearZcfzs(zcfzs);
        xjlls = (ArrayList<Xjll>) getRecentYearXjlls(xjlls);
        profiles = (ArrayList<Profile>) getRecentYearProfiles(profiles);
        mainzbs = (ArrayList<Mainzb>) getRecentYearMainzbs(mainzbs);

        Zdyzb zdyzb = zbDao.getZdyzb();
        List<Fxb> fxbs = zbDao.getFxbs();

        // log.info("zdyzb: {}", zdyzb);
        Zdyzb newZdyzb = Zdyzb.builder()
                .ld(getMainZbString(lastMainzb.getLd()))
                .chzzl(getMainZbString(lastMainzb.getChzzl()))
                .yszkzzts(getMainZbString(lastMainzb.getYszkzzts()))
                .zzczzts(getMainZbString(lastMainzb.getZzczzts()))
                .chzzts(getMainZbString(lastMainzb.getChzzts()))
                .toazzl(getMainZbString(lastMainzb.getToazzl()))
                .yszkzzl(getMainZbString(lastMainzb.getYszkzzl()))
                .roejq(getMainZbString(lastMainzb.getRoejq()))
                .zzcjll(getMainZbString(lastMainzb.getZzcjll()))
                .xsmll(getMainZbString(lastMainzb.getXsmll()))
                .xsjll(getMainZbString(lastMainzb.getXsjll()))
                .sd(getMainZbString(lastMainzb.getSd()))
                .xjllb(getMainZbString(lastMainzb.getXjllb()))
                .zcfzl(getMainZbString(lastMainzb.getZcfzl()))
                .build();
        if (Objects.nonNull(lastMainzb.getTotaloperatereve()) && Objects.nonNull(zcfzs.get(0).getTotalAssets())
                && Objects.nonNull(zcfzs.get(1).getTotalAssets())) {
            newZdyzb.setZbzzl(String.valueOf(lastMainzb.getTotaloperatereve()
                    / (zcfzs.get(0).getTotalAssets() + zcfzs.get(1).getTotalAssets())));
        } else {
            newZdyzb.setZbzzl("该指标为空");
        }
        if (Objects.nonNull(zcfzs.get(0).getTotalAssets()) && Objects.nonNull(zcfzs.get(0).getIntangibleAsset())
                && Objects.nonNull(zcfzs.get(0).getDeferTaxAsset())
                && Objects.nonNull(zcfzs.get(0).getTotalLiabilities())) {
            newZdyzb.setQsjzbl(String.valueOf((zcfzs.get(0).getTotalAssets()
                    - (zcfzs.get(0).getIntangibleAsset() + zcfzs.get(0).getDeferTaxAsset()))
                    / zcfzs.get(0).getTotalLiabilities()));
        } else {
            newZdyzb.setZbzzl("该指标为空");
        }
        if (Objects.nonNull(profiles.get(0).getTotalProfit())
                && Objects.nonNull(profiles.get(0).getFeInterestExpense())) {
            newZdyzb.setLszfbs(
                    String.valueOf(1.0 * profiles.get(0).getTotalProfit() / profiles.get(0).getFeInterestExpense()));
        } else {
            newZdyzb.setLszfbs("该指标为空");
        }

        // 获取营运能力（位运算）
        int sumYingyun = getYingyunSum(lastMainzb, zdyzb);
        // 获取盈利能力
        int sumYingli = getYingliSum(lastMainzb, zdyzb);
        // 偿债能力
        int sumChangZhai = getChangZhaiSum(lastMainzb, zdyzb, profiles.get(0), zcfzs);
        // 担保能力
        int sumDanBao = 0;

        List<RiskReport.Analysis> anas = new ArrayList<>();

        RiskReport.Analysis ana = new RiskReport.Analysis();
        List<RiskReport.ResultZbDto> resultzb = new ArrayList<>();
        resultzb.add(new RiskReport.ResultZbDto("总资产周转天数(天)", newZdyzb.getZzczzts(), getResult(sumYingyun, 5)));
        resultzb.add(new RiskReport.ResultZbDto("存货周转天数(天)", newZdyzb.getChzzts(), getResult(sumYingyun, 4)));
        resultzb.add(new RiskReport.ResultZbDto("应收账款周转天数(天)", newZdyzb.getYszkzzts(), getResult(sumYingyun, 3)));
        resultzb.add(new RiskReport.ResultZbDto("总资产周转率(次)", newZdyzb.getToazzl(), getResult(sumYingyun, 2)));
        resultzb.add(new RiskReport.ResultZbDto("存货周转率(次)", newZdyzb.getChzzl(), getResult(sumYingyun, 1)));
        resultzb.add(new RiskReport.ResultZbDto("应收账款周转率(次)", newZdyzb.getYszkzzl(), getResult(sumYingyun, 0)));
        ana.setType(0);
        ana.setResultZbDtos(resultzb);

        List<Fxb> fxb1 = fxbs.stream().filter(o -> o.getType() == 0).collect(Collectors.toList());
        sumYingyun = getSumForBinary(sumYingyun);
        for (Fxb fxb : fxb1) {
            List<Double> zfzs = MyUtils.getZfz(fxb.getZfz());
            // if (zfzs.size() == 2) {
            if (sumYingyun >= zfzs.get(0) && sumYingyun <= zfzs.get(1)) {
                ana.setRisk(fxb.getFxd());
                ana.setAdvise(fxb.getJy());
            }
            // } else if (zfzs.size() == 1) {
            // if (fxb.getZfz().contains("<")) {
            // if (sumYingyun < zfzs.get(0)) {
            // ana.setRisk(fxb.getFxd());
            // ana.setAdvise(fxb.getJy());
            // }
            // } else if (fxb.getZfz().contains(">")) {
            // if (sumYingyun > zfzs.get(0)) {
            // ana.setRisk(fxb.getFxd());
            // ana.setAdvise(fxb.getJy());
            // }
            // } else {
            // if (sumYingyun == zfzs.get(0)) {
            // ana.setRisk(fxb.getFxd());
            // ana.setAdvise(fxb.getJy());
            // }
            // }
            // else {
            // log.error("com.fuyin.service.user.impl.GpServiceImpl#getRiskReport zfzs: {}, fxb.getZfz(): {}",
            // zfzs, fxb.getZfz());
            // }
        }
        anas.add(ana);

        ana = new RiskReport.Analysis();
        resultzb = new ArrayList<>();
        resultzb.add(new RiskReport.ResultZbDto("净资产收益率(加权)(%)", newZdyzb.getRoejq(), getResult(sumYingli, 3)));
        resultzb.add(new RiskReport.ResultZbDto("总资产收益率(加权)(%)", newZdyzb.getZzcjll(), getResult(sumYingli, 2)));
        resultzb.add(new RiskReport.ResultZbDto("销售毛利率(%)", newZdyzb.getXsmll(), getResult(sumYingli, 1)));
        resultzb.add(new RiskReport.ResultZbDto("销售净利率(%)", newZdyzb.getXsjll(), getResult(sumYingli, 0)));
        ana.setType(1);
        ana.setResultZbDtos(resultzb);

        List<Fxb> fxb2 = fxbs.stream().filter(o -> o.getType() == 1).collect(Collectors.toList());
        sumYingli = getSumForBinary(sumYingli);
        for (Fxb fxb : fxb2) {
            List<Double> zfzs = MyUtils.getBzz(fxb.getZfz());
            // if (zfzs.size() == 2) {
            if (sumYingli >= zfzs.get(0) && sumYingli <= zfzs.get(1)) {
                ana.setRisk(fxb.getFxd());
                ana.setAdvise(fxb.getJy());
            }
            // }
            // } else if (zfzs.size() == 1) {
            // if (fxb.getZfz().contains("<")) {
            // if (sumYingli < zfzs.get(0)) {
            // ana.setRisk(fxb.getFxd());
            // ana.setAdvise(fxb.getJy());
            // }
            // } else if (fxb.getZfz().contains(">")) {
            // if (sumYingli > zfzs.get(0)) {
            // ana.setRisk(fxb.getFxd());
            // ana.setAdvise(fxb.getJy());
            // }
            // } else {
            // if (sumYingli == zfzs.get(0)) {
            // ana.setRisk(fxb.getFxd());
            // ana.setAdvise(fxb.getJy());
            // }
            // }
            // } else {
            // log.error("com.fuyin.service.user.impl.GpServiceImpl#getRiskReport zfzs: {}, fxb.getZfz(): {}",
            // zfzs, fxb.getZfz());
            // }
        }
        anas.add(ana);

        ana = new RiskReport.Analysis();
        resultzb = new ArrayList<>();
        resultzb.add(new RiskReport.ResultZbDto("流动比率", newZdyzb.getLd(), getResult(sumChangZhai, 6)));
        resultzb.add(new RiskReport.ResultZbDto("速动比率", newZdyzb.getSd(), getResult(sumChangZhai, 5)));
        resultzb.add(new RiskReport.ResultZbDto("现金流量比率", newZdyzb.getXjllb(), getResult(sumChangZhai, 4)));
        resultzb.add(new RiskReport.ResultZbDto("资产负债率", newZdyzb.getZcfzl(), getResult(sumChangZhai, 3)));
        resultzb.add(new RiskReport.ResultZbDto("资本周转率", newZdyzb.getZbzzl(), getResult(sumChangZhai, 2)));
        resultzb.add(new RiskReport.ResultZbDto("清算价值比率", newZdyzb.getQsjzbl(), getResult(sumChangZhai, 1)));
        resultzb.add(new RiskReport.ResultZbDto("利息支付倍数", newZdyzb.getLszfbs(), getResult(sumChangZhai, 0)));
        ana.setType(2);
        ana.setResultZbDtos(resultzb);

        List<Fxb> fxb3 = fxbs.stream().filter(o -> o.getType() == 2).collect(Collectors.toList());
        sumChangZhai = getSumForBinary(sumChangZhai);
        for (Fxb fxb : fxb3) {
            List<Double> zfzs = MyUtils.getBzz(fxb.getZfz());
            // if (zfzs.size() == 2) {
            if (sumChangZhai >= zfzs.get(0) && sumChangZhai <= zfzs.get(1)) {
                ana.setRisk(fxb.getFxd());
                ana.setAdvise(fxb.getJy());
            }
            // }
            // } else if (zfzs.size() == 1) {
            // if (fxb.getZfz().contains("<")) {
            // if (sumChangZhai < zfzs.get(0)) {
            // ana.setRisk(fxb.getFxd());
            // ana.setAdvise(fxb.getJy());
            // }
            // } else if (fxb.getZfz().contains(">")) {
            // if (sumChangZhai > zfzs.get(0)) {
            // ana.setRisk(fxb.getFxd());
            // ana.setAdvise(fxb.getJy());
            // }
            // } else {
            // if (sumChangZhai == zfzs.get(0)) {
            // ana.setRisk(fxb.getFxd());
            // ana.setAdvise(fxb.getJy());
            // }
            // }
            // } else {
            // log.error("com.fuyin.service.user.impl.GpServiceImpl#getRiskReport zfzs: {}, fxb.getZfz(): {}",
            // zfzs, fxb.getZfz());
            // }
        }
        anas.add(ana);
        // fxbs.stream().filter(o -> o.getType() == 0).collect(Collectors.toList()));

        GpDetails gpDetail = GpDetails.builder()
                .companyInfo(companyInfo)
                .mainzbs(mainzbs)
                .qygqjgs(qygqjgs)
                .xjlls(xjlls)
                .profiles(profiles)
                .zcfzs(zcfzs)
                .build();
        riskReport.setGpDetails(gpDetail);
        riskReport.setAnalysis(anas);

        ReportInfo reportInfo = new ReportInfo();
        // log.info("token:{}, userName:{}, user:{}, companyInfo:{}", token,
        // jwtTokenUtil.getUserNameFromToken(token),
        // userDao.getUserByUserName(jwtTokenUtil.getUserNameFromToken(token)), companyInfo);
        List<ReportInfo> reportInfos = reportDao.getReportInfosByUserIdAndTitleAndType(
                userDao.getUserByUserName(jwtTokenUtil.getUserNameFromToken(token)).getId(),
                '[' + companyInfo.getAgjc(), 0);
        if (CollectionUtils.isEmpty(reportInfos)) {
            reportInfo.setTitle("[" + companyInfo.getAgjc() + "企业] 融资风险控制方案 " + "1");
        } else {
            reportInfo.setTitle("[" + companyInfo.getAgjc() + "企业] 融资风险控制方案 " + (reportInfos.size() + 1));
        }
        reportInfo.setUserId(user.getId());
        // log.info("riskReport: {}", riskReport);
        // log.info("riskReportJSON: {}", JSON.toJSONString(riskReport));
        try {
            reportInfo.setInfo(MyUtils.objToByte(riskReport));
        } catch (Exception e) {
            log.error("com.fuyin.service.user.impl.GpServiceImpl.getRiskReport e:{} user:{}", e.getMessage(), user);
            return BaseResponse.error(500, "对象转为 byte 失败");
        }
        reportInfo.setType(0);
        // log.info("reportInfo.setInfo: {}", reportInfo.getInfo());
        // reportDao.saveReportInfo(reportInfo);
        return BaseResponse.success(riskReport);
    }

    @Override
    public BaseResponse<ModelReport> getModelReport(String token, RzNeed rzNeed, String gpName) {
        MyUtils.checkParams("股票名不能为空", gpName);
        token = StringUtils.substring(token, tokenHead.length());
        if (Objects.isNull(rzNeed) || StringUtils.isBlank(rzNeed.getCollateral())
                || StringUtils.isBlank(rzNeed.getFiMode()) || StringUtils.isBlank(rzNeed.getRepayMode())
                || StringUtils.isBlank(rzNeed.getPeriod()) || StringUtils.isBlank(rzNeed.getPurpose())
                || StringUtils.isBlank(rzNeed.getGuarantee()) || Objects.isNull(rzNeed.getQuota())) {
            return BaseResponse.error(400, "融资需求不能为空");
        }
        ModelReport modelReport = new ModelReport();
        User user = userDao.getUserByUserName(jwtTokenUtil.getUserNameFromToken(token));
        CompanyInfo companyInfo = gpDao.getCompanyInfoList(gpName);
        if (Objects.isNull(companyInfo)) {
            try {
                pythonApiService.saveData(gpName);
                Thread.sleep(5000);
            } catch (Exception e) {
                log.error("com.fuyin.service.user.impl.GpServiceImpl.getModelReport userName:{},  e:{}, gpName:{}",
                        user.getUserName(), e.getMessage(), gpName);
                return BaseResponse.error(ErrorCode.GP_NOT_SUPPORTED, "暂时不支持该股票的爬取");
            }
        }
        companyInfo = gpDao.getCompanyInfoList(gpName);
        ArrayList<Zcfz> zcfzs = (ArrayList<Zcfz>) gpDao.getZcfzList(gpName);
        zcfzs = (ArrayList<Zcfz>) zcfzs.stream()
                .sorted((o1, o2) -> o1.getReportDate().getTime() > o2.getReportDate().getTime() ? -1 : 1)
                .collect(Collectors.toList());
        ArrayList<Mainzb> mainzbs = (ArrayList<Mainzb>) gpDao.getMainzbList(gpName);
        ArrayList<Profile> profiles = (ArrayList<Profile>) gpDao.getProfileList(gpName);
        ArrayList<Qygqjg> qygqjgs = (ArrayList<Qygqjg>) gpDao.getQygqjgList(profiles.get(0).getSecurityCode());
        ArrayList<Xjll> xjlls = (ArrayList<Xjll>) gpDao.getXjllList(gpName);
        zcfzs = (ArrayList<Zcfz>) getRecentYearZcfzs(zcfzs);
        xjlls = (ArrayList<Xjll>) getRecentYearXjlls(xjlls);
        profiles = (ArrayList<Profile>) getRecentYearProfiles(profiles);
        mainzbs = (ArrayList<Mainzb>) getRecentYearMainzbs(mainzbs);
        GpDetails gpDetails = new GpDetails();
        gpDetails.setCompanyInfo(companyInfo);
        gpDetails.setMainzbs(mainzbs);
        gpDetails.setProfiles(profiles);
        gpDetails.setQygqjgs(qygqjgs);
        gpDetails.setXjlls(xjlls);
        gpDetails.setZcfzs(zcfzs);
        gpDetails.setRzneed(rzNeed);
        modelReport.setGpDetails(gpDetails);

        Mainzb lastMainzb = mainzbs.stream()
                .sorted((o1, o2) -> o1.getReportDate().getTime() > o2.getReportDate().getTime() ? -1 : 1)
                .collect(Collectors.toList()).get(0);
        Zdyzb newZdyzb = Zdyzb.builder()
                .ld(getMainZbString(lastMainzb.getLd()))
                .chzzl(getMainZbString(lastMainzb.getChzzl()))
                .yszkzzts(getMainZbString(lastMainzb.getYszkzzts()))
                .zzczzts(getMainZbString(lastMainzb.getZzczzts()))
                .chzzts(getMainZbString(lastMainzb.getChzzts()))
                .toazzl(getMainZbString(lastMainzb.getToazzl()))
                .yszkzzl(getMainZbString(lastMainzb.getYszkzzl()))
                .roejq(getMainZbString(lastMainzb.getRoejq()))
                .zzcjll(getMainZbString(lastMainzb.getZzcjll()))
                .xsmll(getMainZbString(lastMainzb.getXsmll()))
                .xsjll(getMainZbString(lastMainzb.getXsjll()))
                .sd(getMainZbString(lastMainzb.getSd()))
                .xjllb(getMainZbString(lastMainzb.getXjllb()))
                .zcfzl(getMainZbString(lastMainzb.getZcfzl()))
                .build();
        if (Objects.nonNull(lastMainzb.getTotaloperatereve()) && Objects.nonNull(zcfzs.get(0).getTotalAssets())
                && Objects.nonNull(zcfzs.get(1).getTotalAssets())) {
            newZdyzb.setZbzzl(String.valueOf(lastMainzb.getTotaloperatereve()
                    / (zcfzs.get(0).getTotalAssets() + zcfzs.get(1).getTotalAssets())));
        } else {
            newZdyzb.setZbzzl("该指标为空");
        }
        if (Objects.nonNull(zcfzs.get(0).getTotalAssets()) && Objects.nonNull(zcfzs.get(0).getIntangibleAsset())
                && Objects.nonNull(zcfzs.get(0).getDeferTaxAsset())
                && Objects.nonNull(zcfzs.get(0).getTotalLiabilities())) {
            newZdyzb.setQsjzbl(String.valueOf((zcfzs.get(0).getTotalAssets()
                    - (zcfzs.get(0).getIntangibleAsset() + zcfzs.get(0).getDeferTaxAsset()))
                    / zcfzs.get(0).getTotalLiabilities()));
        } else {
            newZdyzb.setZbzzl("该指标为空");
        }
        if (Objects.nonNull(profiles.get(0).getTotalProfit())
                && Objects.nonNull(profiles.get(0).getFeInterestExpense())) {
            newZdyzb.setLszfbs(
                    String.valueOf(1.0 * profiles.get(0).getTotalProfit() / profiles.get(0).getFeInterestExpense()));
        } else {
            newZdyzb.setLszfbs("该指标为空");
        }

        ArrayList<RiskReport.ResultZbDto> resultZbDtos = new ArrayList<>();
        resultZbDtos.add(new RiskReport.ResultZbDto("流动比率", newZdyzb.getLd()));
        resultZbDtos.add(new RiskReport.ResultZbDto("速动比率", newZdyzb.getSd()));
        resultZbDtos.add(new RiskReport.ResultZbDto("现金流量比率", newZdyzb.getXjllb()));
        resultZbDtos.add(new RiskReport.ResultZbDto("资产负债率 (%)", newZdyzb.getZcfzl()));
        resultZbDtos.add(new RiskReport.ResultZbDto("资本周转率", newZdyzb.getZbzzl()));
        resultZbDtos.add(new RiskReport.ResultZbDto("清算价值比率", newZdyzb.getQsjzbl()));
        resultZbDtos.add(new RiskReport.ResultZbDto("利息支付倍数", newZdyzb.getLszfbs()));
        if (Objects.nonNull(profiles.get(0).getTotalProfit()) && Objects.nonNull(profiles.get(0).getOperateIncome())) {
            resultZbDtos.add(new RiskReport.ResultZbDto("销售利润率",
                    String.valueOf(profiles.get(0).getTotalProfit() / profiles.get(0).getOperateIncome())));
        } else {
            resultZbDtos.add(new RiskReport.ResultZbDto("销售利润率", "该指标为空"));
        }
        if (Objects.nonNull(profiles.get(0).getTotalProfit())
                && Objects.nonNull(profiles.get(0).getTotalOperateCost())) {
            resultZbDtos.add(new RiskReport.ResultZbDto("成本费用利润率",
                    String.valueOf(profiles.get(0).getTotalProfit() / profiles.get(0).getTotalOperateCost())));
        } else {
            resultZbDtos.add(new RiskReport.ResultZbDto("成本费用利润率", "该指标为空"));
        }
        if (Objects.nonNull(profiles.get(0).getTotalProfit()) && Objects.nonNull(zcfzs.get(0).getTotalAssets())
                && Objects.nonNull(zcfzs.get(1).getTotalAssets())) {
            resultZbDtos.add(new RiskReport.ResultZbDto("总资产利润率", String.valueOf(profiles.get(0).getTotalProfit()
                    / (zcfzs.get(0).getTotalAssets() + zcfzs.get(1).getTotalAssets()) / 2.0)));
        } else {
            resultZbDtos.add(new RiskReport.ResultZbDto("总资产利润率", "该指标为空"));
        }
        if (Objects.nonNull(profiles.get(0).getTotalProfit()) && Objects.nonNull(zcfzs.get(0).getShareCapital())) {
            resultZbDtos.add(new RiskReport.ResultZbDto("资本金利润率",
                    String.valueOf(profiles.get(0).getTotalProfit() / (zcfzs.get(0).getShareCapital()))));
        } else {
            resultZbDtos.add(new RiskReport.ResultZbDto("资本金利润率", "该指标为空"));
        }
        if (Objects.nonNull(profiles.get(0).getTotalProfit()) && Objects.nonNull(zcfzs.get(0).getTotalEquity())
                && Objects.nonNull(zcfzs.get(1).getTotalEquity())) {
            resultZbDtos.add(new RiskReport.ResultZbDto("股东权益利润率", String.valueOf(profiles.get(0).getTotalProfit()
                    / (zcfzs.get(0).getTotalEquity() + zcfzs.get(1).getTotalEquity()))));
        } else {
            resultZbDtos.add(new RiskReport.ResultZbDto("股东权益利润率", "该指标为空"));
        }
        modelReport.setResultZbDtos(resultZbDtos);

        List<ModelSum> modelSums = zbDao.getModelSum();
        List<ZdyzbModel> zdyzbModels = zbDao.getZdyzbModel();
        Integer sumCznl = getZbModelScore(
                zdyzbModels.stream().filter(x -> x.getZbKey().equals("ld")).collect(Collectors.toList()),
                newZdyzb.getLd())
                + getZbModelScore(
                        zdyzbModels.stream().filter(x -> x.getZbKey().equals("sd")).collect(Collectors.toList()),
                        newZdyzb.getSd())
                + getZbModelScore(
                        zdyzbModels.stream().filter(x -> x.getZbKey().equals("xjllb")).collect(Collectors.toList()),
                        newZdyzb.getXjllb())
                + getZbModelScore(
                        zdyzbModels.stream().filter(x -> x.getZbKey().equals("zcfzl")).collect(Collectors.toList()),
                        newZdyzb.getZcfzl())
                + getZbModelScore(
                        zdyzbModels.stream().filter(x -> x.getZbKey().equals("zbzzl")).collect(Collectors.toList()),
                        newZdyzb.getZbzzl())
                + getZbModelScore(
                        zdyzbModels.stream().filter(x -> x.getZbKey().equals("qsjzbl")).collect(Collectors.toList()),
                        newZdyzb.getQsjzbl())
                + getZbModelScore(
                        zdyzbModels.stream().filter(x -> x.getZbKey().equals("lszfbs")).collect(Collectors.toList()),
                        newZdyzb.getLszfbs());

        Integer sumYlnl = 0;
        if (Objects.nonNull(profiles.get(0).getTotalProfit()) && Objects.nonNull(profiles.get(0).getOperateIncome())) {
            sumYlnl += getZbModelScore(
                    zdyzbModels.stream().filter(x -> x.getZbKey().equals("xslrl")).collect(Collectors.toList()),
                    String.valueOf(profiles.get(0).getTotalProfit() / profiles.get(0).getOperateIncome()));
        }
        if (Objects.nonNull(profiles.get(0).getTotalProfit())
                && Objects.nonNull(profiles.get(0).getTotalOperateCost())) {
            sumYlnl += getZbModelScore(
                    zdyzbModels.stream().filter(x -> x.getZbKey().equals("cbfylrl")).collect(Collectors.toList()),
                    String.valueOf(profiles.get(0).getTotalProfit() / profiles.get(0).getTotalOperateCost()));
        }
        if (Objects.nonNull(profiles.get(0).getTotalProfit()) && Objects.nonNull(zcfzs.get(0).getTotalAssets())
                && Objects.nonNull(zcfzs.get(1).getTotalAssets())) {
            sumYlnl += getZbModelScore(
                    zdyzbModels.stream().filter(x -> x.getZbKey().equals("zzclrl")).collect(Collectors.toList()),
                    String.valueOf(profiles.get(0).getTotalProfit()
                            / (zcfzs.get(0).getTotalAssets() + zcfzs.get(1).getTotalAssets()) / 2.0));
        }
        if (Objects.nonNull(profiles.get(0).getTotalProfit()) && Objects.nonNull(zcfzs.get(0).getShareCapital())) {
            sumYlnl += getZbModelScore(
                    zdyzbModels.stream().filter(x -> x.getZbKey().equals("zbjlrl")).collect(Collectors.toList()),
                    String.valueOf(profiles.get(0).getTotalProfit() / (zcfzs.get(0).getShareCapital())));
        }
        if (Objects.nonNull(profiles.get(0).getTotalProfit()) && Objects.nonNull(zcfzs.get(0).getTotalEquity())
                && Objects.nonNull(zcfzs.get(1).getTotalEquity())) {
            sumYlnl += getZbModelScore(
                    zdyzbModels.stream().filter(x -> x.getZbKey().equals("zbjlrl")).collect(Collectors.toList()),
                    String.valueOf(profiles.get(0).getTotalProfit()
                            / (zcfzs.get(0).getTotalEquity() + zcfzs.get(1).getTotalEquity())));
        }
        Integer cznl =
                getType(modelSums.stream().filter(x -> x.getAbility() == 0).collect(Collectors.toList()), sumCznl);
        Integer ylnl =
                getType(modelSums.stream().filter(x -> x.getAbility() == 1).collect(Collectors.toList()), sumYlnl);
        Double ppd = 0.0;

        List<Rzppd> rzppds = zbDao.getRzppd();
        for (Rzppd rzppd : rzppds) {
            if (rzppd.getCznl().equals(cznl) && rzppd.getYlnl().equals(ylnl)
                    && Objects.nonNull(zcfzs.get(0).getTotalAssets())) {
                if (judgeBz(rzppd.getBz(), zcfzs.get(0).getTotalAssets() / rzNeed.getQuota())) {
                    ppd = rzppd.getPpd();
                }
            }
        }
        modelReport.setAnalysis("通过对" + companyInfo.getGsmc() + "企业财务状况分析，当前企业具有" + modelAbilityMap.get(cznl) + "的偿债能力和"
                + modelAbilityMap.get(ylnl) + "的盈利能力， 且企业的现金流、资产和股票未来持有价值"
                + (zcfzs.get(0).getTotalAssets() / rzNeed.getQuota() >= 1 ? ">=" : "<") + "需融资的金额，所以匹配度达到" + ppd * 100
                + "%以上;");

        ReportInfo reportInfo = new ReportInfo();
        reportInfo.setType(1);
        List<ReportInfo> reportInfos = reportDao.getReportInfosByUserIdAndTitleAndType(
                userDao.getUserByUserName(jwtTokenUtil.getUserNameFromToken(token)).getId(),
                '[' + companyInfo.getAgjc(), 1);
        if (CollectionUtils.isEmpty(reportInfos)) {
            reportInfo.setTitle("[" + companyInfo.getAgjc() + "企业] 融资方案分析报告 " + "1");
        } else {
            reportInfo.setTitle("[" + companyInfo.getAgjc() + "企业] 融资方案分析报告 " + (reportInfos.size() + 1));
        }
        try {
            reportInfo.setInfo(MyUtils.objToByte(modelReport));
        } catch (Exception e) {
            log.error("com.fuyin.service.user.impl.GpServiceImpl.getModelReport e:{} user:{}", e, user);
            return BaseResponse.error(500, "对象转为 byte 失败");
        }
        reportInfo.setUserId(user.getId());
        // reportDao.saveReportInfo(reportInfo);

        Product product = productDao.getProducts() == null ? null : productDao.getProducts().get(0);
        modelReport.setProduct(product);
        return BaseResponse.success(modelReport);
    }

    @Override
    public BaseResponse<ArrayList<RiskReport.Analysis>> getAnalysis(GpDetails gpDetails) {
        if (Objects.isNull(gpDetails) || CollectionUtils.isEmpty(gpDetails.getMainzbs()) ||
                CollectionUtils.isEmpty(gpDetails.getProfiles()) ||
                CollectionUtils.isEmpty(gpDetails.getQygqjgs()) ||
                CollectionUtils.isEmpty(gpDetails.getXjlls()) ||
                CollectionUtils.isEmpty(gpDetails.getZcfzs())) {
            throw new ApiException(400, "参数不全");
        }

        Mainzb lastMainzb = gpDetails.getMainzbs().get(0);
        Zdyzb zdyzb = zbDao.getZdyzb();
        List<Fxb> fxbs = zbDao.getFxbs();
        List<Profile> profiles = gpDetails.getProfiles();
        List<Zcfz> zcfzs = gpDetails.getZcfzs();
        // 获取营运能力（位运算）
        int sumYingyun = getYingyunSum(lastMainzb, zdyzb);
        // 获取盈利能力
        int sumYingli = getYingliSum(lastMainzb, zdyzb);
        // 偿债能力
        int sumChangZhai = getChangZhaiSum(lastMainzb, zdyzb, profiles.get(0), zcfzs);
        // 担保能力
        int sumDanBao = 0;

        Zdyzb newZdyzb = Zdyzb.builder()
                .ld(getMainZbString(lastMainzb.getLd()))
                .chzzl(getMainZbString(lastMainzb.getChzzl()))
                .yszkzzts(getMainZbString(lastMainzb.getYszkzzts()))
                .zzczzts(getMainZbString(lastMainzb.getZzczzts()))
                .chzzts(getMainZbString(lastMainzb.getChzzts()))
                .toazzl(getMainZbString(lastMainzb.getToazzl()))
                .yszkzzl(getMainZbString(lastMainzb.getYszkzzl()))
                .roejq(getMainZbString(lastMainzb.getRoejq()))
                .zzcjll(getMainZbString(lastMainzb.getZzcjll()))
                .xsmll(getMainZbString(lastMainzb.getXsmll()))
                .xsjll(getMainZbString(lastMainzb.getXsjll()))
                .sd(getMainZbString(lastMainzb.getSd()))
                .xjllb(getMainZbString(lastMainzb.getXjllb()))
                .zcfzl(getMainZbString(lastMainzb.getZcfzl()))
                .build();

        ArrayList<RiskReport.Analysis> anas = new ArrayList<>();

        RiskReport.Analysis ana = new RiskReport.Analysis();
        List<RiskReport.ResultZbDto> resultzb = new ArrayList<>();
        resultzb.add(new RiskReport.ResultZbDto("总资产周转天数(天)", newZdyzb.getZzczzts(), getResult(sumYingyun, 5)));
        resultzb.add(new RiskReport.ResultZbDto("存货周转天数(天)", newZdyzb.getChzzts(), getResult(sumYingyun, 4)));
        resultzb.add(new RiskReport.ResultZbDto("应收账款周转天数(天)", newZdyzb.getYszkzzts(), getResult(sumYingyun, 3)));
        resultzb.add(new RiskReport.ResultZbDto("总资产周转率(次)", newZdyzb.getToazzl(), getResult(sumYingyun, 2)));
        resultzb.add(new RiskReport.ResultZbDto("存货周转率(次)", newZdyzb.getChzzl(), getResult(sumYingyun, 1)));
        resultzb.add(new RiskReport.ResultZbDto("应收账款周转率(次)", newZdyzb.getYszkzzl(), getResult(sumYingyun, 0)));
        ana.setType(0);
        ana.setResultZbDtos(resultzb);

        List<Fxb> fxb1 = fxbs.stream().filter(o -> o.getType() == 0).collect(Collectors.toList());
        sumYingyun = getSumForBinary(sumYingyun);
        for (Fxb fxb : fxb1) {
            List<Double> zfzs = MyUtils.getZfz(fxb.getZfz());
            // if (zfzs.size() == 2) {
            if (sumYingyun >= zfzs.get(0) && sumYingyun <= zfzs.get(1)) {
                ana.setRisk(fxb.getFxd());
                ana.setAdvise(fxb.getJy());
            }
        }
        anas.add(ana);

        ana = new RiskReport.Analysis();
        resultzb = new ArrayList<>();
        resultzb.add(new RiskReport.ResultZbDto("净资产收益率(加权)(%)", newZdyzb.getRoejq(), getResult(sumYingli, 3)));
        resultzb.add(new RiskReport.ResultZbDto("总资产收益率(加权)(%)", newZdyzb.getZzcjll(), getResult(sumYingli, 2)));
        resultzb.add(new RiskReport.ResultZbDto("销售毛利率(%)", newZdyzb.getXsmll(), getResult(sumYingli, 1)));
        resultzb.add(new RiskReport.ResultZbDto("销售净利率(%)", newZdyzb.getXsjll(), getResult(sumYingli, 0)));
        ana.setType(1);
        ana.setResultZbDtos(resultzb);

        List<Fxb> fxb2 = fxbs.stream().filter(o -> o.getType() == 1).collect(Collectors.toList());
        sumYingli = getSumForBinary(sumYingli);
        for (Fxb fxb : fxb2) {
            List<Double> zfzs = MyUtils.getBzz(fxb.getZfz());
            // if (zfzs.size() == 2) {
            if (sumYingli >= zfzs.get(0) && sumYingli <= zfzs.get(1)) {
                ana.setRisk(fxb.getFxd());
                ana.setAdvise(fxb.getJy());
            }
        }
        anas.add(ana);

        ana = new RiskReport.Analysis();
        resultzb = new ArrayList<>();
        resultzb.add(new RiskReport.ResultZbDto("流动比率", newZdyzb.getLd(), getResult(sumChangZhai, 6)));
        resultzb.add(new RiskReport.ResultZbDto("速动比率", newZdyzb.getSd(), getResult(sumChangZhai, 5)));
        resultzb.add(new RiskReport.ResultZbDto("现金流量比率", newZdyzb.getXjllb(), getResult(sumChangZhai, 4)));
        resultzb.add(new RiskReport.ResultZbDto("资产负债率", newZdyzb.getZcfzl(), getResult(sumChangZhai, 3)));
        resultzb.add(new RiskReport.ResultZbDto("资本周转率", newZdyzb.getZbzzl(), getResult(sumChangZhai, 2)));
        resultzb.add(new RiskReport.ResultZbDto("清算价值比率", newZdyzb.getQsjzbl(), getResult(sumChangZhai, 1)));
        resultzb.add(new RiskReport.ResultZbDto("利息支付倍数", newZdyzb.getLszfbs(), getResult(sumChangZhai, 0)));
        ana.setType(2);
        ana.setResultZbDtos(resultzb);

        List<Fxb> fxb3 = fxbs.stream().filter(o -> o.getType() == 2).collect(Collectors.toList());
        sumChangZhai = getSumForBinary(sumChangZhai);
        for (Fxb fxb : fxb3) {
            List<Double> zfzs = MyUtils.getBzz(fxb.getZfz());
            // if (zfzs.size() == 2) {
            if (sumChangZhai >= zfzs.get(0) && sumChangZhai <= zfzs.get(1)) {
                ana.setRisk(fxb.getFxd());
                ana.setAdvise(fxb.getJy());
            }
        }
        anas.add(ana);
        return BaseResponse.success(anas);
    }

    @Override
    public BaseResponse saveRiskReportInfo(String token, RiskReport riskReport) {
        log.info("riskReport: {}", riskReport);
        if (Objects.isNull(riskReport)) {
            return BaseResponse.error(400, "参数不全");
        }
        token = token.substring(this.tokenHead.length());
        ReportInfo reportInfo = new ReportInfo();
        CompanyInfo companyInfo = riskReport.getGpDetails().getCompanyInfo();
        if (Objects.isNull(companyInfo)) {
            throw new ApiException("公司信息不能为空");
        }
        User user = userDao.getUserByUserName(jwtTokenUtil.getUserNameFromToken(token));
        List<ReportInfo> reportInfos = reportDao.getReportInfosByUserIdAndTitleAndType(
                userDao.getUserByUserName(jwtTokenUtil.getUserNameFromToken(token)).getId(),
                '[' + companyInfo.getAgjc(), 0);
        if (CollectionUtils.isEmpty(reportInfos)) {
            reportInfo.setTitle("[" + companyInfo.getAgjc() + "企业] 融资风险控制方案 " + "1");
        } else {
            reportInfo.setTitle("[" + companyInfo.getAgjc() + "企业] 融资风险控制方案 " + (reportInfos.size() + 1));
        }
        reportInfo.setUserId(user.getId());
        try {
            reportInfo.setInfo(MyUtils.objToByte(riskReport));
        } catch (Exception e) {
            log.error("com.fuyin.service.user.impl.GpServiceImpl.saveRiskReportInfo e:{} user:{}", e, user);
            return BaseResponse.error(500, "对象转为 byte 失败");
        }
        reportInfo.setType(0);
        reportDao.saveReportInfo(reportInfo);
        return BaseResponse.success();
    }

    @Override
    public BaseResponse saveModelReportInfo(String token, ModelReport modelReport) {
        if (Objects.isNull(modelReport)) {
            throw new ApiException("参数不全");
        }
        ReportInfo reportInfo = new ReportInfo();
        reportInfo.setType(1);
        token = token.substring(this.tokenHead.length());
        CompanyInfo companyInfo = modelReport.getGpDetails().getCompanyInfo();
        if (Objects.isNull(companyInfo)) {
            throw new ApiException("公司信息不能为空");
        }
        User user = userDao.getUserByUserName(jwtTokenUtil.getUserNameFromToken(token));
        List<ReportInfo> reportInfos = reportDao.getReportInfosByUserIdAndTitleAndType(
                userDao.getUserByUserName(jwtTokenUtil.getUserNameFromToken(token)).getId(),
                '[' + companyInfo.getAgjc(), 1);
        if (CollectionUtils.isEmpty(reportInfos)) {
            reportInfo.setTitle("[" + companyInfo.getAgjc() + "企业] 融资方案分析报告 " + "1");
        } else {
            reportInfo.setTitle("[" + companyInfo.getAgjc() + "企业] 融资方案分析报告 " + (reportInfos.size() + 1));
        }
        try {
            reportInfo.setInfo(MyUtils.objToByte(modelReport));
        } catch (Exception e) {
            log.error("com.fuyin.service.user.impl.GpServiceImpl.getModelReport e:{} user:{}", e.getMessage(), user);
            return BaseResponse.error(500, "对象转为 byte 失败");
        }
        reportInfo.setUserId(user.getId());
        reportDao.saveReportInfo(reportInfo);
        return BaseResponse.success();
    }

    @Override
    public BaseResponse<String> getModelAnalysis(GpDetails gpDetails) {
        if (Objects.isNull(gpDetails)) {
            throw new ApiException("参数不全");
        }
        Mainzb lastMainzb = gpDetails.getMainzbs().stream()
                .sorted((o1, o2) -> o1.getReportDate().getTime() > o2.getReportDate().getTime() ? -1 : 1)
                .collect(Collectors.toList()).get(0);
        Zdyzb newZdyzb = Zdyzb.builder()
                .ld(getMainZbString(lastMainzb.getLd()))
                .chzzl(getMainZbString(lastMainzb.getChzzl()))
                .yszkzzts(getMainZbString(lastMainzb.getYszkzzts()))
                .zzczzts(getMainZbString(lastMainzb.getZzczzts()))
                .chzzts(getMainZbString(lastMainzb.getChzzts()))
                .toazzl(getMainZbString(lastMainzb.getToazzl()))
                .yszkzzl(getMainZbString(lastMainzb.getYszkzzl()))
                .roejq(getMainZbString(lastMainzb.getRoejq()))
                .zzcjll(getMainZbString(lastMainzb.getZzcjll()))
                .xsmll(getMainZbString(lastMainzb.getXsmll()))
                .xsjll(getMainZbString(lastMainzb.getXsjll()))
                .sd(getMainZbString(lastMainzb.getSd()))
                .xjllb(getMainZbString(lastMainzb.getXjllb()))
                .zcfzl(getMainZbString(lastMainzb.getZcfzl()))
                .build();
        List<ModelSum> modelSums = zbDao.getModelSum();
        List<ZdyzbModel> zdyzbModels = zbDao.getZdyzbModel();
        Integer sumCznl = getZbModelScore(
                zdyzbModels.stream().filter(x -> x.getZbKey().equals("ld")).collect(Collectors.toList()),
                newZdyzb.getLd())
                + getZbModelScore(
                        zdyzbModels.stream().filter(x -> x.getZbKey().equals("sd")).collect(Collectors.toList()),
                        newZdyzb.getSd())
                + getZbModelScore(
                        zdyzbModels.stream().filter(x -> x.getZbKey().equals("xjllb")).collect(Collectors.toList()),
                        newZdyzb.getXjllb())
                + getZbModelScore(
                        zdyzbModels.stream().filter(x -> x.getZbKey().equals("zcfzl")).collect(Collectors.toList()),
                        newZdyzb.getZcfzl())
                + getZbModelScore(
                        zdyzbModels.stream().filter(x -> x.getZbKey().equals("zbzzl")).collect(Collectors.toList()),
                        newZdyzb.getZbzzl())
                + getZbModelScore(
                        zdyzbModels.stream().filter(x -> x.getZbKey().equals("qsjzbl")).collect(Collectors.toList()),
                        newZdyzb.getQsjzbl())
                + getZbModelScore(
                        zdyzbModels.stream().filter(x -> x.getZbKey().equals("lszfbs")).collect(Collectors.toList()),
                        newZdyzb.getLszfbs());
        List<Profile> profiles = gpDetails.getProfiles();
        List<Zcfz> zcfzs = gpDetails.getZcfzs();
        CompanyInfo companyInfo = gpDetails.getCompanyInfo();
        Integer sumYlnl = 0;
        if (Objects.nonNull(profiles.get(0).getTotalProfit()) && Objects.nonNull(profiles.get(0).getOperateIncome())) {
            sumYlnl += getZbModelScore(
                    zdyzbModels.stream().filter(x -> x.getZbKey().equals("xslrl")).collect(Collectors.toList()),
                    String.valueOf(profiles.get(0).getTotalProfit() / profiles.get(0).getOperateIncome()));
        }
        if (Objects.nonNull(profiles.get(0).getTotalProfit())
                && Objects.nonNull(profiles.get(0).getTotalOperateCost())) {
            sumYlnl += getZbModelScore(
                    zdyzbModels.stream().filter(x -> x.getZbKey().equals("cbfylrl")).collect(Collectors.toList()),
                    String.valueOf(profiles.get(0).getTotalProfit() / profiles.get(0).getTotalOperateCost()));
        }
        if (Objects.nonNull(profiles.get(0).getTotalProfit()) && Objects.nonNull(zcfzs.get(0).getTotalAssets())
                && Objects.nonNull(zcfzs.get(1).getTotalAssets())) {
            sumYlnl += getZbModelScore(
                    zdyzbModels.stream().filter(x -> x.getZbKey().equals("zzclrl")).collect(Collectors.toList()),
                    String.valueOf(profiles.get(0).getTotalProfit()
                            / (zcfzs.get(0).getTotalAssets() + zcfzs.get(1).getTotalAssets()) / 2.0));
        }
        if (Objects.nonNull(profiles.get(0).getTotalProfit()) && Objects.nonNull(zcfzs.get(0).getShareCapital())) {
            sumYlnl += getZbModelScore(
                    zdyzbModels.stream().filter(x -> x.getZbKey().equals("zbjlrl")).collect(Collectors.toList()),
                    String.valueOf(profiles.get(0).getTotalProfit() / (zcfzs.get(0).getShareCapital())));
        }
        if (Objects.nonNull(profiles.get(0).getTotalProfit()) && Objects.nonNull(zcfzs.get(0).getTotalEquity())
                && Objects.nonNull(zcfzs.get(1).getTotalEquity())) {
            sumYlnl += getZbModelScore(
                    zdyzbModels.stream().filter(x -> x.getZbKey().equals("zbjlrl")).collect(Collectors.toList()),
                    String.valueOf(profiles.get(0).getTotalProfit()
                            / (zcfzs.get(0).getTotalEquity() + zcfzs.get(1).getTotalEquity())));
        }
        Integer cznl =
                getType(modelSums.stream().filter(x -> x.getAbility() == 0).collect(Collectors.toList()), sumCznl);
        Integer ylnl =
                getType(modelSums.stream().filter(x -> x.getAbility() == 1).collect(Collectors.toList()), sumYlnl);
        Double ppd = 0.0;

        List<Rzppd> rzppds = zbDao.getRzppd();
        for (Rzppd rzppd : rzppds) {
            if (rzppd.getCznl().equals(cznl) && rzppd.getYlnl().equals(ylnl)
                    && Objects.nonNull(zcfzs.get(0).getTotalAssets())) {
                if (judgeBz(rzppd.getBz(), zcfzs.get(0).getTotalAssets() / gpDetails.getRzneed().getQuota())) {
                    ppd = rzppd.getPpd();
                }
            }
        }
        return BaseResponse.success("通过对" + companyInfo.getGsmc() + "企业财务状况分析，当前企业具有" + modelAbilityMap.get(cznl)
                + "的偿债能力和" + modelAbilityMap.get(ylnl) + "的盈利能力， 且企业的现金流、资产和股票未来持有价值"
                + (zcfzs.get(0).getTotalAssets() / gpDetails.getRzneed().getQuota() >= 1 ? ">=" : "<")
                + "需融资的金额，所以匹配度达到" + ppd * 100 + "%以上;");
    }

    private int getType(List<ModelSum> modelSums, Integer sum) {
        for (ModelSum model : modelSums) {
            String equation = model.getEquation();
            if (equation.contains("<")) {
                if (sum < Double.parseDouble(equation.substring(1))) {
                    return model.getType();
                }
            } else if (equation.contains(">")) {
                if (sum > Double.parseDouble(equation.substring(1))) {
                    return model.getType();
                }
            } else if (equation.contains("-")) {
                int indexx = equation.indexOf("-");
                if (sum >= Double.parseDouble(equation.substring(0, indexx))
                        && sum <= Double.parseDouble(equation.substring(indexx + 1))) {
                    return model.getType();
                }
            }
        }
        log.error("com.fuyin.service.user.impl.GpServiceImpl.getType error");
        return -1;
    }

    private int getZbModelScore(List<ZdyzbModel> zdyzbModels, String value1) {
        Double value;
        try {
            value = Double.parseDouble(value1);
        } catch (Exception e) {
            return 0;
        }
        for (ZdyzbModel zdyzbModel : zdyzbModels) {
            String equation = zdyzbModel.getEquation();
            if (equation.contains("<")) {
                if (value < Double.parseDouble(equation.substring(1))) {
                    return zdyzbModel.getScore();
                }
            } else if (equation.contains(">")) {
                if (value > Double.parseDouble(equation.substring(1))) {
                    return zdyzbModel.getScore();
                }
            } else if (equation.contains("-")) {
                int indexx = equation.indexOf("-");
                if (value >= Double.parseDouble(equation.substring(0, indexx))
                        && value <= Double.parseDouble(equation.substring(indexx + 1))) {
                    return zdyzbModel.getScore();
                }
            }
        }
        log.error("com.fuyin.service.user.impl.GpServiceImpl.getZbModelScore not found score");
        return 0;
    }

    private boolean judgeBz(String zb, Double value) {
        if (zb.contains("x")) {
            if (zb.contains("<")) {
                String[] pre = zb.split("<");
                if (pre.length == 3)
                    return value > Double.parseDouble(pre[0]) && value < Double.parseDouble(pre[2]);
            } else if (zb.contains(">")) {
                String[] pre = zb.split(">");
                if (pre.length == 3)
                    return value > Double.parseDouble(pre[2]) && value < Double.parseDouble(pre[0]);
            }
        }
        if (zb.contains(">")) {
            int index = zb.indexOf(">") + 1;
            return value > Double.parseDouble(zb.substring(index));
        }
        if (zb.contains(">=")) {
            int index = zb.indexOf("=") + 1;
            return value >= Double.parseDouble(zb.substring(index));
        }
        if (zb.contains("<")) {
            int index = zb.indexOf("<") + 1;
            return value < Double.parseDouble(zb.substring(index));
        }
        if (zb.contains("<=")) {
            int index = zb.indexOf("=") + 1;
            return value <= Double.parseDouble(zb.substring(index));
        }
        if (zb.contains("-")) {
            String[] pre = zb.split("-");
            return value >= Double.parseDouble(pre[0]) && value <= Double.parseDouble(pre[1]);
        }
        return false;
    }

    private int getSumForBinary(Integer k) {
        int ans = 0;
        while (k > 0) {
            ans += k & 1;
            k >>= 1;
        }
        return ans;
    }

    private String getMainZbString(Double zb) {
        if (Objects.isNull(zb)) {
            return "该指标为空";
        }
        return zb.toString();
    }

    private String getResult(int sum, int cnt) {
        while (cnt-- > 0) {
            sum >>= 1;
        }
        return (sum & 1) == 1 ? "正常" : "不正常";
    }

    private int getChangZhaiSum(Mainzb mainzb, Zdyzb zdyzb, Profile profile, List<Zcfz> zcfzs) {
        if (Objects.isNull(mainzb) || Objects.isNull(zdyzb) || Objects.isNull(profile) || Objects.isNull(zcfzs)) {
            log.error(
                    "com.fuyin.service.user.impl.GpServiceImpl#getChangZhaiSum mainzb: {}, zdyzb: {}, profile: {}, zcfzs: {}",
                    mainzb, zdyzb, profile, zcfzs);
            return 0;
        }
        List<Double> ld = MyUtils.getBzz(zdyzb.getLd());
        List<Double> sd = MyUtils.getBzz(zdyzb.getSd());
        List<Double> xjllb = MyUtils.getBzz(zdyzb.getXjllb());
        List<Double> zcfzl = MyUtils.getBzz(zdyzb.getZcfzl());
        List<Double> zbzzl = MyUtils.getBzz(zdyzb.getZbzzl());
        List<Double> qsjzbl = MyUtils.getBzz(zdyzb.getQsjzbl());
        List<Double> lszfbs = MyUtils.getBzz(zdyzb.getLszfbs());

        int sum = 0;
        if (Objects.nonNull(mainzb.getLd()) && mainzb.getLd() >= ld.get(0) && mainzb.getLd() <= ld.get(1)) sum |= 1;
        sum <<= 1;
        if (Objects.nonNull(mainzb.getSd()) && mainzb.getSd() >= sd.get(0) && mainzb.getSd() <= sd.get(1))
            sum |= 1;
        sum <<= 1;
        if (Objects.nonNull(mainzb.getXjllb()) && mainzb.getXjllb() >= xjllb.get(0)
                && mainzb.getXjllb() <= xjllb.get(1))
            sum |= 1;
        sum <<= 1;
        if (Objects.nonNull(mainzb.getZcfzl()) && mainzb.getZcfzl() >= zcfzl.get(0)
                && mainzb.getZcfzl() <= zcfzl.get(1))
            sum |= 1;
        sum <<= 1;
        if (Objects.nonNull(mainzb.getTotaloperatereve()) && Objects.nonNull(zcfzs.get(0).getTotalAssets())
                && Objects.nonNull(zcfzs.get(1).getTotalAssets())
                && mainzb.getTotaloperatereve()
                        / (zcfzs.get(0).getTotalAssets() + zcfzs.get(1).getTotalAssets()) >= zbzzl.get(0)
                && mainzb.getTotaloperatereve()
                        / (zcfzs.get(0).getTotalAssets() + zcfzs.get(1).getTotalAssets()) <= zbzzl.get(1))
            sum |= 1;
        sum <<= 1;
        if (Objects.nonNull(zcfzs.get(0).getTotalAssets()) && Objects.nonNull(zcfzs.get(0).getIntangibleAsset())
                && Objects.nonNull(zcfzs.get(0).getDeferTaxAsset())
                && Objects.nonNull(zcfzs.get(0).getTotalLiabilities())) {
            double qingsuan = (zcfzs.get(0).getTotalAssets()
                    - (zcfzs.get(0).getIntangibleAsset() + zcfzs.get(0).getDeferTaxAsset()))
                    / zcfzs.get(0).getTotalLiabilities();
            if (qingsuan >= qsjzbl.get(0) && qingsuan <= qsjzbl.get(1)) sum |= 1;
        }
        sum <<= 1;
        if (Objects.nonNull(profile.getTotalProfit()) && Objects.nonNull(profile.getFeInterestExpense())
                && 1.0 * profile.getTotalProfit() / profile.getFeInterestExpense() >= lszfbs.get(0)
                && 1.0 * profile.getTotalProfit() / profile.getFeInterestExpense() <= lszfbs.get(1))
            sum |= 1;

        return sum;
    }

    private int getYingliSum(Mainzb mainzb, Zdyzb zdyzb) {
        if (Objects.isNull(mainzb) || Objects.isNull(zdyzb)) {
            log.error("com.fuyin.service.user.impl.GpServiceImpl#getYingliSum mainzb: {}, zdyzb: {}", mainzb, zdyzb);
            return 0;
        }
        List<Double> roejq = MyUtils.getBzz(zdyzb.getRoejq());
        List<Double> zzcjll = MyUtils.getBzz(zdyzb.getZzcjll());
        List<Double> xsmll = MyUtils.getBzz(zdyzb.getXsmll());
        List<Double> xsjll = MyUtils.getBzz(zdyzb.getXsjll());

        int sum = 0;
        if (Objects.nonNull(mainzb.getRoejq()) && mainzb.getRoejq() >= roejq.get(0)
                && mainzb.getRoejq() <= roejq.get(1))
            sum |= 1;
        sum <<= 1;
        if (Objects.nonNull(mainzb.getZzcjll()) && mainzb.getZzcjll() >= zzcjll.get(0)
                && mainzb.getZzcjll() <= zzcjll.get(1))
            sum |= 1;
        sum <<= 1;
        if (Objects.nonNull(mainzb.getXsmll()) && mainzb.getXsmll() >= xsmll.get(0)
                && mainzb.getXsmll() <= xsmll.get(1))
            sum |= 1;
        sum <<= 1;
        if (Objects.nonNull(mainzb.getXsjll()) && mainzb.getXsjll() >= xsjll.get(0)
                && mainzb.getXsjll() <= xsjll.get(1))
            sum |= 1;
        return sum;
    }

    private int getYingyunSum(Mainzb mainzb, Zdyzb zdyzb) {
        if (Objects.isNull(mainzb) || Objects.isNull(zdyzb)) {
            log.error("com.fuyin.service.user.impl.GpServiceImpl#getYingyunSum mainzb: {}, zdyzb: {}", mainzb, zdyzb);
            return 0;
        }
        List<Double> zzczzts = MyUtils.getBzz(zdyzb.getZzczzts());
        List<Double> chzzts = MyUtils.getBzz(zdyzb.getChzzts());
        List<Double> yszkzzts = MyUtils.getBzz(zdyzb.getYszkzzts());
        List<Double> toazzl = MyUtils.getBzz(zdyzb.getToazzl());
        List<Double> chzzl = MyUtils.getBzz(zdyzb.getChzzl());
        List<Double> yszkzzl = MyUtils.getBzz(zdyzb.getYszkzzl());

        int sum = 0;
        if (Objects.nonNull(mainzb.getZzczzts()) && mainzb.getZzczzts() >= zzczzts.get(0)
                && mainzb.getZzczzts() <= zzczzts.get(1))
            sum |= 1;
        sum <<= 1;
        if (Objects.nonNull(mainzb.getChzzts()) && mainzb.getChzzts() >= chzzts.get(0)
                && mainzb.getChzzts() <= chzzts.get(1))
            sum |= 1;
        sum <<= 1;
        if (Objects.nonNull(mainzb.getYszkzzts()) && mainzb.getYszkzzts() >= yszkzzts.get(0)
                && mainzb.getYszkzzts() <= yszkzzts.get(1))
            sum |= 1;
        sum <<= 1;
        if (Objects.nonNull(mainzb.getToazzl()) && mainzb.getToazzl() >= toazzl.get(0)
                && mainzb.getToazzl() <= toazzl.get(1))
            sum |= 1;
        sum <<= 1;
        if (Objects.nonNull(mainzb.getChzzl()) && mainzb.getChzzl() >= chzzl.get(0)
                && mainzb.getChzzl() <= chzzl.get(1))
            sum |= 1;
        sum <<= 1;
        if (Objects.nonNull(mainzb.getYszkzzl()) && mainzb.getYszkzzl() >= yszkzzl.get(0)
                && mainzb.getYszkzzl() <= yszkzzl.get(1))
            sum |= 1;
        return sum;
    }

    private List<Zcfz> getRecentYearZcfzs(List<Zcfz> zcfzs) {
        zcfzs = zcfzs.stream().sorted(Comparator.comparing(Zcfz::getReportDate).reversed())
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(zcfzs)) {
            return zcfzs;
        }
        List<Zcfz> ans =
                zcfzs.stream().filter(o -> DateUtil.month(o.getReportDate()) == 11).collect(Collectors.toList());
        ans = CollectionUtil.sub(ans, 0, 3);
        if (DateUtil.month(zcfzs.get(0).getReportDate()) != 11) {
            ans.add(0, zcfzs.get(0));
        }
        return ans;
    }

    private List<Xjll> getRecentYearXjlls(List<Xjll> xjlls) {
        xjlls = xjlls.stream().sorted(Comparator.comparing(Xjll::getReportDate).reversed())
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(xjlls)) {
            return xjlls;
        }
        List<Xjll> ans =
                xjlls.stream().filter(o -> DateUtil.month(o.getReportDate()) == 11).collect(Collectors.toList());
        ans = CollectionUtil.sub(ans, 0, 3);
        if (DateUtil.month(xjlls.get(0).getReportDate()) != 11) {
            ans.add(0, xjlls.get(0));
        }
        return ans;
    }

    private List<Mainzb> getRecentYearMainzbs(List<Mainzb> mainzbs) {
        mainzbs = mainzbs.stream().sorted(Comparator.comparing(Mainzb::getReportDate).reversed())
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(mainzbs)) {
            return mainzbs;
        }
        List<Mainzb> ans =
                mainzbs.stream().filter(o -> DateUtil.month(o.getReportDate()) == 11).collect(Collectors.toList());
        ans = CollectionUtil.sub(ans, 0, 3);
        if (DateUtil.month(mainzbs.get(0).getReportDate()) != 11) {
            ans.add(0, mainzbs.get(0));
        }
        return ans;
    }

    private List<Profile> getRecentYearProfiles(List<Profile> profiles) {
        profiles = profiles.stream().sorted(Comparator.comparing(Profile::getReportDate).reversed())
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(profiles)) {
            return profiles;
        }
        List<Profile> ans =
                profiles.stream().filter(o -> DateUtil.month(o.getReportDate()) == 11).collect(Collectors.toList());
        ans = CollectionUtil.sub(ans, 0, 3);
        if (DateUtil.month(profiles.get(0).getReportDate()) != 11) {
            ans.add(0, profiles.get(0));
        }
        return ans;
    }
}
